//! 基本使用示例
//! 展示如何使用 unified_api 框架

use unified_api::{auth::{AuthPolicy, AuthContext, AuthRequest, AuthResult}, routers::RouteInfo};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct User {
    id: u64,
    name: String,
    email: String,
}

// 示例API处理器
async fn get_users() -> Result<serde_json::Value, String> {
    let users = vec![
        User {
            id: 1,
            name: "Alice".to_string(),
            email: "alice@example.com".to_string(),
        },
        User {
            id: 2,
            name: "Bob".to_string(),
            email: "bob@example.com".to_string(),
        },
    ];

    Ok(serde_json::json!({
        "users": users,
        "total": users.len()
    }))
}

async fn get_user_by_id(id: u64) -> Result<serde_json::Value, String> {
    if id == 1 {
        let user = User {
            id: 1,
            name: "Alice".to_string(),
            email: "alice@example.com".to_string(),
        };
        Ok(serde_json::json!(user))
    } else {
        Err("User not found".to_string())
    }
}

// 公开的API，不需要认证
async fn health_check() -> Result<serde_json::Value, String> {
    Ok(serde_json::json!({
        "status": "healthy",
        "timestamp": "2024-01-01T00:00:00Z"
    }))
}

// 自定义认证策略示例
struct CustomAuthPolicy {
    secret_key: String,
}

impl AuthPolicy for CustomAuthPolicy {
    fn authenticate(&self, request: &AuthRequest) -> AuthResult<AuthContext> {
        // 这里实现自定义的认证逻辑
        if let Some(token) = request.headers.get("X-Custom-Token") {
            if token == "valid-token" {
                let mut context = AuthContext::new("user123".to_string());
                context.username = Some("custom_user".to_string());
                context.roles = vec!["user".to_string()];
                context.permissions = vec!["users.read".to_string()];
                
                Ok(context)
            } else {
                Err(unified_api::auth::AuthError::InvalidToken("Invalid custom token".to_string()))
            }
        } else {
            Err(unified_api::auth::AuthError::InvalidToken("Missing custom token".to_string()))
        }
    }

    fn check_permission(&self, context: &AuthContext, required_policy: &str) -> AuthResult<bool> {
        if required_policy.is_empty() {
            return Ok(true);
        }

        if required_policy.starts_with("permission:") {
            let permission = &required_policy[11..];
            Ok(context.has_permission(permission))
        } else if required_policy.starts_with("role:") {
            let role = &required_policy[5..];
            Ok(context.has_role(role))
        } else if required_policy.starts_with("user:") {
            let user_id = &required_policy[5..];
            Ok(context.user_id == user_id)
        } else {
            Ok(true)
        }
    }
}

fn main() {
    println!("Unified API Framework Example");
    
    // 创建路由信息
    let routes = vec![
        RouteInfo::new("/api/users", "GET", "get_users")
            .with_auth_policy("permission:users.read")
            .with_description("获取所有用户列表")
            .with_tags(vec!["users", "admin"]),
            
        RouteInfo::new("/api/users/{id}", "GET", "get_user_by_id")
            .with_auth_policy("permission:users.read")
            .with_description("根据ID获取用户信息")
            .with_tags(vec!["users"]),
            
        RouteInfo::new("/api/health", "GET", "health_check")
            .with_auth_policy("") // 空字符串表示不需要认证
            .with_description("健康检查接口")
            .with_tags(vec!["health"]),
    ];
    
    println!("Configured {} routes:", routes.len());
    for (i, route) in routes.iter().enumerate() {
        println!("  {}. {} {} - {}", i + 1, route.method, route.path, 
                 route.description.as_deref().unwrap_or("No description"));
    }
    
    // 这里可以启动web服务器
    // 根据启用的特性选择相应的框架
    
    #[cfg(feature = "actix")]
    {
        println!("Actix-web support enabled");
    }
    
    #[cfg(feature = "rocket")]
    {
        println!("Rocket support enabled");
    }
    
    #[cfg(feature = "axum")]
    {
        println!("Axum support enabled");
    }
    
    #[cfg(feature = "jwt")]
    {
        println!("JWT support enabled");
    }
    
    #[cfg(feature = "swagger")]
    {
        println!("Swagger documentation support enabled");
    }
}